{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## ARTEAR 2021.11"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### Csound的使用"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(4096, 2)\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "import ctcsound\n",
    "import sounddevice as sd\n",
    "\n",
    "# Defining our Csound ORC code within a triple-quoted, multiline String\n",
    "orc = \"\"\"\n",
    "sr=44100\n",
    "ksmps=64\n",
    "nchnls=2\n",
    "0dbfs=1\n",
    "\n",
    "\n",
    "\n",
    "instr 1\n",
    "a1 oscil 10000, 440, 1\n",
    "outs a1, a1\n",
    "endin\n",
    "instr 2\n",
    "a1 oscil 10000, 440, 2\n",
    "outs a1, a1\n",
    "endin\"\"\"\n",
    "\n",
    "\n",
    "# Defining our Csound SCO code\n",
    "sco = \"\"\"\n",
    "f1 0 1024 10 1 ; Sine\n",
    "f2 0 1024 10 1 0 0.3 0 0.2 0 0.14 0 .111 ; Square\n",
    "f3 0 1024 10 1 0.5 0.3 0.25 0.2 0.167 0.14 0.125 .111 ; Saw\n",
    "\n",
    "i1 0 2\n",
    "i2 2 2\"\"\"\n",
    "\n",
    "c = ctcsound.Csound()\n",
    "c.setOption(\"-odac\")  # Using SetOption() to configure Csound\n",
    "# Note: use only one commandline flag at a time\n",
    "\n",
    "c.compileOrc(orc)     # Compile the Csound Orchestra string\n",
    "c.readScore(sco)      # Compile the Csound SCO String\n",
    "c.start()             # When compiling from strings, this call is necessary\n",
    "# before doing any performing\n",
    "c.perform()           # Run Csound to completion\n",
    "# c.stop()\n",
    "buff = c.outputBuffer().reshape(-1, 2)\n",
    "c.setOutput()\n",
    "#sd.play(buff, 44100)\n",
    "print(buff.shape)\n",
    "c.reset()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "#### 可视化工具PyQtGragh的使用"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "17.0\n",
      "1.9\n",
      "4.7\n",
      "4.9\n",
      "1.3\n",
      "1.6\n",
      "8.7\n",
      "2.1\n"
     ]
    }
   ],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\"\"\"\n",
    "This example demonstrates many of the 2D plotting capabilities\n",
    "in pyqtgraph. All of the plots may be panned/scaled by dragging with\n",
    "the left/right mouse buttons. Right click on any plot to show a context menu.\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "\n",
    "from pyqtgraph.Qt import QtGui, QtCore\n",
    "import numpy as np\n",
    "import pyqtgraph as pg\n",
    "\n",
    "app = pg.mkQApp(\"Plotting Example\")\n",
    "#mw = QtGui.QMainWindow()\n",
    "#mw.resize(800,800)\n",
    "\n",
    "win = pg.GraphicsLayoutWidget(show=True, title=\"Basic plotting examples\")\n",
    "win.resize(1000,600)\n",
    "win.setWindowTitle('pyqtgraph example: Plotting')\n",
    "\n",
    "# Enable antialiasing for prettier plots\n",
    "pg.setConfigOptions(antialias=True)\n",
    "\n",
    "'''p1 = win.addPlot(title=\"Basic array plotting\", y=np.random.normal(size=100))\n",
    "\n",
    "p2 = win.addPlot(title=\"Multiple curves\")\n",
    "p2.plot(np.random.normal(size=100), pen=(255,0,0), name=\"Red curve\")\n",
    "p2.plot(np.random.normal(size=110)+5, pen=(0,255,0), name=\"Green curve\")\n",
    "p2.plot(np.random.normal(size=120)+10, pen=(0,0,255), name=\"Blue curve\")\n",
    "\n",
    "p3 = win.addPlot(title=\"Drawing with points\")\n",
    "p3.plot(np.random.normal(size=100), pen=(200,200,200), symbolBrush=(255,0,0), symbolPen='w')\n",
    "\n",
    "\n",
    "win.nextRow()\n",
    "\n",
    "p4 = win.addPlot(title=\"Parametric, grid enabled\")\n",
    "x = np.cos(np.linspace(0, 2*np.pi, 1000))\n",
    "y = np.sin(np.linspace(0, 4*np.pi, 1000))\n",
    "p4.plot(x, y)\n",
    "p4.showGrid(x=True, y=True)\n",
    "\n",
    "p5 = win.addPlot(title=\"Scatter plot, axis labels, log scale\")\n",
    "x = np.random.normal(size=1000) * 1e-5\n",
    "y = x*1000 + 0.005 * np.random.normal(size=1000)\n",
    "y -= y.min()-1.0\n",
    "mask = x > 1e-15\n",
    "x = x[mask]\n",
    "y = y[mask]\n",
    "p5.plot(x, y, pen=None, symbol='t', symbolPen=None, symbolSize=10, symbolBrush=(100, 100, 255, 50))\n",
    "p5.setLabel('left', \"Y Axis\", units='A')\n",
    "p5.setLabel('bottom', \"Y Axis\", units='s')\n",
    "p5.setLogMode(x=True, y=False)'''\n",
    "\n",
    "p6 = win.addPlot(title=\"Updating plot\")\n",
    "curve = p6.plot(pen='y')\n",
    "data = np.random.normal(size=(10,1000))\n",
    "ptr = 0\n",
    "def update():\n",
    "    global curve, data, ptr, p6\n",
    "    curve.setData(data[ptr%10])\n",
    "    if ptr == 0:\n",
    "        p6.enableAutoRange('xy', False)  ## stop auto-scaling after the first data set is plotted\n",
    "    ptr += 1\n",
    "timer = QtCore.QTimer()\n",
    "timer.timeout.connect(update)\n",
    "timer.start(50)\n",
    "\n",
    "\n",
    "'''win.nextRow()\n",
    "\n",
    "p7 = win.addPlot(title=\"Filled plot, axis disabled\")\n",
    "y = np.sin(np.linspace(0, 10, 1000)) + np.random.normal(size=1000, scale=0.1)\n",
    "p7.plot(y, fillLevel=-0.3, brush=(50,50,200,100))\n",
    "p7.showAxis('bottom', False)\n",
    "\n",
    "\n",
    "x2 = np.linspace(-100, 100, 1000)\n",
    "data2 = np.sin(x2) / x2\n",
    "p8 = win.addPlot(title=\"Region Selection\")\n",
    "p8.plot(data2, pen=(255,255,255,200))\n",
    "lr = pg.LinearRegionItem([400,700])\n",
    "lr.setZValue(-10)\n",
    "p8.addItem(lr)\n",
    "\n",
    "p9 = win.addPlot(title=\"Zoom on selected region\")\n",
    "p9.plot(data2)\n",
    "def updatePlot():\n",
    "    p9.setXRange(*lr.getRegion(), padding=0)\n",
    "def updateRegion():\n",
    "    lr.setRegion(p9.getViewBox().viewRange()[0])\n",
    "lr.sigRegionChanged.connect(updatePlot)\n",
    "p9.sigXRangeChanged.connect(updateRegion)\n",
    "updatePlot()'''\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    pg.exec()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "usage: ipykernel_launcher.py [-h] [-l] [-d DEVICE] [-r SAMPLERATE]\n",
      "                             [-c CHANNELS] [-t SUBTYPE]\n",
      "                             [FILENAME]\n",
      "ipykernel_launcher.py: error: unrecognized arguments: -f\n"
     ]
    },
    {
     "ename": "SystemExit",
     "evalue": "2",
     "output_type": "error",
     "traceback": [
      "An exception has occurred, use %tb to see the full traceback.\n",
      "\u001B[1;31mSystemExit\u001B[0m\u001B[1;31m:\u001B[0m 2\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\python\\python39\\lib\\site-packages\\IPython\\core\\interactiveshell.py:3449: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
      "  warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
     ]
    }
   ],
   "source": [
    "\n",
    "#!/usr/bin/env python3\n",
    "\"\"\"Create a recording with arbitrary duration.\n",
    "\n",
    "The soundfile module (https://PySoundFile.readthedocs.io/) has to be installed!\n",
    "\n",
    "\"\"\"\n",
    "import argparse\n",
    "import tempfile\n",
    "import queue\n",
    "import sys\n",
    "\n",
    "import sounddevice as sd\n",
    "import soundfile as sf\n",
    "import numpy  # Make sure NumPy is loaded before it is used in the callback\n",
    "assert numpy  # avoid \"imported but unused\" message (W0611)\n",
    "\n",
    "\n",
    "def int_or_str(text):\n",
    "    \"\"\"Helper function for argument parsing.\"\"\"\n",
    "    try:\n",
    "        return int(text)\n",
    "    except ValueError:\n",
    "        return text\n",
    "\n",
    "\n",
    "parser = argparse.ArgumentParser(add_help=False)\n",
    "parser.add_argument(\n",
    "    '-l', '--list-devices', action='store_true',\n",
    "    help='show list of audio devices and exit')\n",
    "args, remaining = parser.parse_known_args()\n",
    "if args.list_devices:\n",
    "    print(sd.query_devices())\n",
    "    parser.exit(0)\n",
    "parser = argparse.ArgumentParser(\n",
    "    description=__doc__,\n",
    "    formatter_class=argparse.RawDescriptionHelpFormatter,\n",
    "    parents=[parser])\n",
    "parser.add_argument(\n",
    "    'filename', nargs='?', metavar='FILENAME',\n",
    "    help='audio file to store recording to')\n",
    "parser.add_argument(\n",
    "    '-d', '--device', type=int_or_str,\n",
    "    help='input device (numeric ID or substring)')\n",
    "parser.add_argument(\n",
    "    '-r', '--samplerate', type=int, help='sampling rate')\n",
    "parser.add_argument(\n",
    "    '-c', '--channels', type=int, default=1, help='number of input channels')\n",
    "parser.add_argument(\n",
    "    '-t', '--subtype', type=str, help='sound file subtype (e.g. \"PCM_24\")')\n",
    "args = parser.parse_args(remaining)\n",
    "\n",
    "q = queue.Queue()\n",
    "\n",
    "\n",
    "def callback(indata, frames, time, status):\n",
    "    \"\"\"This is called (from a separate thread) for each audio block.\"\"\"\n",
    "    if status:\n",
    "        print(status, file=sys.stderr)\n",
    "    q.put(indata.copy())\n",
    "\n",
    "\n",
    "try:\n",
    "    if args.samplerate is None:\n",
    "        device_info = sd.query_devices(args.device, 'input')\n",
    "        # soundfile expects an int, sounddevice provides a float:\n",
    "        args.samplerate = int(device_info['default_samplerate'])\n",
    "    if args.filename is None:\n",
    "        args.filename = tempfile.mktemp(prefix='delme_rec_unlimited_',\n",
    "                                        suffix='.wav', dir='')\n",
    "\n",
    "    # Make sure the file is opened before recording anything:\n",
    "    with sf.SoundFile(args.filename, mode='x', samplerate=args.samplerate,\n",
    "                      channels=args.channels, subtype=args.subtype) as file:\n",
    "        with sd.InputStream(samplerate=args.samplerate, device=args.device,\n",
    "                            channels=args.channels, callback=callback):\n",
    "            print('#' * 80)\n",
    "            print('press Ctrl+C to stop the recording')\n",
    "            print('#' * 80)\n",
    "            while True:\n",
    "                file.write(q.get())\n",
    "except KeyboardInterrupt:\n",
    "    print('\\nRecording finished: ' + repr(args.filename))\n",
    "    parser.exit(0)\n",
    "except Exception as e:\n",
    "    parser.exit(type(e).__name__ + ': ' + str(e))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}